package com.simpleim.starter.handler;

import com.simpleim.common.task.CallableTaskScheduler;
import com.simpleim.common.task.CallbackTask;
import com.simpleim.im.common.bean.msg.ProtoMsg;
import com.simpleim.starter.processor.LoginProcesser;
import com.simpleim.starter.server.ServerSession;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 登录处理器
 */
@Service
@ChannelHandler.Sharable
public class LoginRequestHandler extends ChannelInboundHandlerAdapter {

    private static final Logger log = LoggerFactory.getLogger(LoginRequestHandler.class);

    @Autowired
    private HeartBeatServerHandler heartBeatServerHandler;

    @Autowired
    private ChatRedirectHandler chatRedirectHandler;

    @Autowired
    private LoginProcesser loginProcesser;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (!(msg instanceof ProtoMsg.Message)) {
            // 直接调用下一个handler进行处理
            super.channelRead(ctx, msg);
            return;
        }
        ProtoMsg.Message message = (ProtoMsg.Message) msg;

        ProtoMsg.HeadType headType = message.getType();

        // 如果不是登录请求，直接送下一步
        if (headType != ProtoMsg.HeadType.LOGIN_REQUEST) {
            super.channelRead(ctx, msg);
            return;
        }

        // 获取用户名和密码进行登录
        // 这里会涉及到查库或者比较耗时的操作，具体业务处理以异步的方式进行
        ProtoMsg.LoginRequest loginRequest = message.getLoginRequest();
        String userId = loginRequest.getUserId();

        // 构建ServerSession
        Channel channel = ctx.channel();
        ServerSession session = new ServerSession(channel);

        CallableTaskScheduler.add(new CallbackTask<Boolean>() {
            @Override
            public Boolean execute() throws Exception {
                return loginProcesser.action(session, message);
            }

            @Override
            public void onBack(Boolean r) {
                if (r) {
                    // 登录成果逻辑
                    channel.pipeline().addAfter("login", "heartBeat", heartBeatServerHandler);
                    channel.pipeline().addAfter("login", "chatRedirec", chatRedirectHandler);

                    channel.pipeline().remove("login");

                    session.bind();

                    // 把消息进行回写
                } else {
                    ServerSession.closeSession(ctx);
                    log.info("登录失败:" + session.getUser());
                }
            }

            @Override
            public void onException(Throwable exception) {
                ServerSession.closeSession(ctx);
                log.info("登录异常:" + session.getUser());
            }
        });
    }
}
